# utility.rb (v1.0)

#   DO NOT MODIFY THIS FILE
#   This file should NOT be included in your submission to the submission server
#   A copy of utility.rb will already be on the submission server.
#   Your code in assignment2.rb CAN make use of the methods here if desired

# -------------------------------------------------------------------------
# reads a CSV file and returns an array of lines read

def read_file(file)
    lines = IO.readlines(file)
    if lines != nil
        for i in 1 .. lines.length-1
            lines[i] = lines[i].sub("\n","")
        end
        return lines[1..lines.length-1]
    end
    return nil
end
# -------------------------------------------------------------------------
# reads data from source (CSV file), constructs a weighted graph based on the CSV file, 
# and sets global variable $g to the graph
def load_graph(source)
    g = WGraph.new

    # load graph from source CSV
    read_file(source).each{ |line|
        array = line.split(",")
        
        actor1 = array[0]
        actor2 = array[1]   # actor2 and edge_weight could be nil if there is no edge
        edge_weight = array[2] 
        
#        p "reading: " + line # you can comment this line if desired
        
        # add actor1 to graph
        v1 = g.get_vertex(actor1)
        if (v1 == nil) # actor1 does not exist as a vertex on the graph yet
            v1 = Vertex.new(actor1)
            g.add_vertex(v1)
        end
        
        # add actor2 to graph
        if (actor2 != nil)
            v2 = g.get_vertex(actor2)
            if (v2 == nil) # actor2 does not exist as a vertex on the graph yet
                v2 = Vertex.new(actor2)
                g.add_vertex(v2)
            end
        
            # add edge to graph
            g.add_edge(v1, v2, edge_weight)
        end
    }
    return g
end
# -------------------------------------------------------------------------
# input: an array of actor names
# retuns: true if the chain of actors is valid in $g, false otherwise
def check_valid_chain(g, actor_list) # actors is an array of actor names
    if actor_list == nil
        return nil
    end
    
    for i in 0..actor_list.size-2
        current_vertex = g.get_vertex(actor_list[i])
        next_vertex = g.get_vertex(actor_list[i+1])
        
        if (current_vertex == nil)
            p "no such vertex " + actor_list[i]
            return false
        end

        if (next_vertex == nil)
            p "no such vertex " + actor_list[i+1]
            return false
        end
        
        if (!current_vertex.adjList.include?(next_vertex))
            p "no link from " + current_vertex.to_s + " to " + next_vertex.to_s
            return false
        end
    end
    return true
end
# -------------------------------------------------------------------------
# input: an array of actor names
# returns: total weight of all edges in the chain of actors or INFINITY if the chain is not valid
def get_total_weight(g, actor_list) # actors is an array of actor names
    total_weight = 0.0
    for i in 0..actor_list.size-2
        current_vertex = g.get_vertex(actor_list[i])
        next_vertex = g.get_vertex(actor_list[i+1])
        weight = g.get_edge_weight(current_vertex, next_vertex)
        if (weight == nil) # no edge
            return Integer::INFINITY
        end
        total_weight = total_weight + weight
    end    
    return total_weight
end

# -------------------------------------------------------------------------
# input: an array of actor names
# returns: true if all the actors in the input array are not directly linked. false otherwise
def check_valid_independent_set(g, actor_list) # actor_list is an array of actors
    for i in 0..actor_list.size-1
        first_vertex = g.get_vertex(actor_list[i])
        for j in 0..actor_list.size-1
            second_vertex = g.get_vertex(actor_list[j])
            # check if first_vertex and second_vertex are adjacent
            if (first_vertex != second_vertex && first_vertex.adjList.include?(second_vertex))
                p "These two vertices are adjacent: (" + first_vertex.to_s + "), (" + second_vertex.to_s + ")" # comment out this line if desired
                return false
            end 
        end
    end
    return true
end
# -------------------------------------------------------------------------
# input: an array of actor names
# output: a string containing the actor names separated by commas
# this method is useful for preparing a string of arrays for printing
def get_display_string(actor_list) # actor_list is an array of actors
    if actor_list == nil
        return "nil"
    end

    result = ""
    for i in 0..actor_list.size-2
        result = result + actor_list[i].to_s + ", "
    end
    # add last fellow to result outside loop to avoid trailing commas
    result = result + actor_list[actor_list.size-1].to_s 
    return result
end
